<?php

/**
 * Biblioteka realizujące żadania REST i spawdzająca czy żądanie aplikacji było wywołane z grono.net
 *
 * @package    gronoApps
 *
 * @author     Marcin Chyłek (songoq) <marcin@chylek.pl>
 *             http://blog.chylek.pl
 *             http://ampluso.pl
 *
 * @example    http://code.google.com/p/gronoapps/wiki/Przyklady_uzycia
 * @license    http://www.opensource.org/licenses/mit-license.php The MIT License
 * @link       http://code.google.com/p/gronoapps/wiki/ChangeLog
 *
 * @version    SVN: $Id$
 */
class gronoApps
{
  private
    $secretKey    = '',
    $publicKey    = '',
    $formatREST   = 'JSON',
    $gronoUrlREST = 'http://grono.net/pub/app/restserver/',
    $params       = array(),
    $lastError    = array();
  
  /**
   * Konstruktor
   *
   * @param string  $gronoSecretKey  Secret Key przyznawany aplikacji przez grono.net
   * @param string  $gronoPublicKey  Pulic Key przyznawany aplikacji przez grono.net
   */
  public function __construct( $gronoSecretKey, $gronoPublicKey )
  {
    $this->secretKey = $gronoSecretKey;
    $this->publicKey = $gronoPublicKey;
  }
  
  /**
   * Zwrócenie id przyjaciół na podstawie $gronoUID
   *
   * @param int $gronoUID grono_uid
   * @return Array Tablica grono_uid'ow użytkowników, którzy są przyjaciółmi
   * Array
   * (
   *   [0] => 1046978
   * )
   */
  public function getMethod_friendsGet( $gronoUID )
  {
    $this->params['grono_method'] = 'grono.friends.get';
    $this->params['grono_uid']    = $gronoUID;
    $this->params['format']       = $this->formatREST;
        
    return $this->sendRequest();
  }
  
  /**
   * Metoda zwracająca tablice informacje o użytkowniku na podstawie $gronoUID
   *
   * @param int $gronoUID grono_uid
   * @return array  Informacje o użytkowniku
   * Array
   * (
   *   [city]    => Warszawa
   *   [scrname] => SongoQ
   *   [surname] => Chyłek
   *   [name]    => Marcin
   *   [age]     => 26
   *   [sex]     => M
   *   [motto]   => Ustawiam status
   *  )
   */
  public function getMethod_usersGetInfo( $gronoUID )
  {
    $this->params['grono_method'] = 'grono.users.getInfo';
    $this->params['grono_uid']    = $gronoUID;
    $this->params['format']       = $this->formatREST;
    
    return $this->sendRequest();
  }
  
  /**
   * Sprawdzanie czy request z zewnatrz jest wykonany przez grono.net
   *
   * @return boolean true / false
   */
  public function isValidateRequest()
  {
    if( isset( $_GET['grono_uid'] ) )
      $this->params = $_GET;
    else if( isset( $_POST['grono_uid'] ) )
      $this->params = $_POST;
    else
      return false;

    $sig = isset( $this->params['grono_sig'] ) ? $this->params['grono_sig'] : '';
    
    if( $sig == $this->buildSig() )
      return true;
    else
      return false;
  }
  
  /**
   * Tablica z błędami ostatniego request'a
   *
   * @return array Tablica z błędami ostatniego request'a
   */
  public function lastError()
  {
    return $this->lastError;
  }
  
  /**
   * Budowanie hash grono_sig na podstawie parametrów
   *
   * @return string grono_sig
   */
  private function buildSig()
  {
    $gronoParams = $this->params;
    
    $gronoParams['grono_public_key'] = $this->publicKey;
    $gronoParams['grono_secret_key'] = $this->secretKey;
    
    unset( $gronoParams['grono_sig'] );
    ksort( $gronoParams );
    
    $hash = '';

    foreach( $gronoParams as $key => $values )
    {
       if( is_array( $values ) )
       {
         ksort( $values );

         foreach( $values as $subKey => $value )
         {
           $hash .= $key.'['.$subKey.']='.$value;
         }
       }
       else
         $hash .= $key.'='.$values;
    }

    /**
     * Jeśli serwer slashuje to czyscimy
     */
    $hash = stripslashes( $hash );
    $sig = md5( $hash );
        
    return $sig;
  }
  
  /**
   * REST do serwera Grono.net i zwracanie odpowiednich danych
   *
   * @return array or false - Array - w przypadku powodzenia, false - błąd
   */
  private function sendRequest()
  {
    $sig           = $this->buildSig();
    $gronoParams   = $this->params;
    $paramsRequest = '';
    
    $gronoParams['grono_public_key'] = $this->publicKey;
    $gronoParams['grono_sig']        = $sig;
    
    foreach( $gronoParams as $key => $value )
      $paramsRequest .= $key.'='.$value.'&';
    
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, $this->gronoUrlREST );
    curl_setopt( $ch, CURLOPT_POST, 1 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $paramsRequest );
    
    $result = curl_exec( $ch );
    curl_close( $ch );
    
    $resultRequest = json_decode( $result, true );
    
    if( $resultRequest['status'] == '1' )
    {
      $this->lastError['description'] = $resultRequest['description'];
      $this->lastError['error']       = $resultRequest['error'];
      
      return false;
    }
    else
    {
      return $resultRequest['data'][$gronoParams['grono_method']];
    }
  }
}

